package com.ruoyi.shop.modules.service.impl;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;

import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.shop.common.utils.RedisIdWorker;
import com.ruoyi.shop.modules.domain.UserGroup;
import com.ruoyi.shop.modules.domain.Voucher;
import com.ruoyi.shop.modules.domain.VoucherOrder;
import com.ruoyi.shop.modules.mapper.VoucherMapper;
import com.ruoyi.shop.modules.mapper.VoucherOrderMapper;
import com.ruoyi.shop.modules.service.IVoucherService;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


/**
 * 优惠券Service业务层处理
 * 
 * @author bcxj
 * @date 2024-07-02
 */
@Service
public class VoucherServiceImpl implements IVoucherService
{
    @Autowired
    private VoucherMapper voucherMapper;
    @Autowired
    private VoucherOrderMapper voucherOrderMapper;
    @Autowired
    private RedisIdWorker redisIdWorker;

    /**
     * 查询优惠券
     * 
     * @param id 优惠券主键
     * @return 优惠券
     */
    @Override
    public Voucher selectVoucherById(String id)
    {
        return voucherMapper.selectVoucherById(id);
    }

    /**
     * 查询优惠券列表
     * 
     * @param voucher 优惠券
     * @return 优惠券
     */
    @Override
    public List<Voucher> selectVoucherList(Voucher voucher)
    {
        return voucherMapper.selectVoucherList(voucher);
    }

    /**
     * 新增优惠券
     * 
     * @param voucher 优惠券
     * @return 结果
     */
    @Override
    public int insertVoucher(Voucher voucher)
    {
        voucher.setCreateTime(DateUtils.getNowDate());
        return voucherMapper.insertVoucher(voucher);
    }

    /**
     * 修改优惠券
     * 
     * @param voucher 优惠券
     * @return 结果
     */
    @Override
    public int updateVoucher(Voucher voucher)
    {
        voucher.setUpdateTime(DateUtils.getNowDate());
        return voucherMapper.updateVoucher(voucher);
    }

    /**
     * 批量删除优惠券
     * 
     * @param ids 需要删除的优惠券主键
     * @return 结果
     */
    @Override
    public int deleteVoucherByIds(String[] ids)
    {
        return voucherMapper.deleteVoucherByIds(ids);
    }

    /**
     * 删除优惠券信息
     * 
     * @param id 优惠券主键
     * @return 结果
     */
    @Override
    public int deleteVoucherById(String id)
    {
        return voucherMapper.deleteVoucherById(id);
    }


    /**
     * 优惠卷秒杀
     * @param voucherId
     * @return
     */
    @Override
    public AjaxResult seckillVoucherByIds(Long voucherId) {

        // 1 获取优惠卷的信息
        if(null == voucherId){
            return AjaxResult.error("数据发送异常");
        }
        Voucher voucher = voucherMapper.selectVoucherById(voucherId.toString());

        // 1.2 判断当前的优惠卷时间是否合理
        if (LocalDateTime.now().isBefore(data2LocalDateTime(voucher.getBeginTime()))) {
            return AjaxResult.error("优惠卷还未开始");
        }
        if (LocalDateTime.now().isAfter(data2LocalDateTime(voucher.getEndTime()))){
            return AjaxResult.error("优惠卷已经结束");
        }

        // 2 判断当前的优惠卷的库存是否足够
        if (voucher.getStock() <= 0) {
            return AjaxResult.error("优惠卷已经售完");
        }

        // 注意Spring事务失效的问题
        // 	所以Spring的底层掌握是多么的重要
        synchronized (voucherId.toString().intern()) {
            VoucherServiceImpl proxy = (VoucherServiceImpl) AopContext.currentProxy();
            // 4 生成订单
            return proxy.createOrder(voucherId);
        }
    }


    /**
     * 下单操作，一人一单，并发超卖问题
     * @param voucherId
     * @return
     */
    @Transactional
    @Override
    public AjaxResult createOrder(Long voucherId) {
        // 2.2.一人一单逻辑
        // 2.2.1.用户id
        Long userId = SecurityUtils.getUserId();
        int count = voucherOrderMapper.selectVoucherOrderByVoucherIdAndUserId(userId, voucherId);
        // 5.2.判断是否存在
        if (count > 0) {
            // 用户已经购买过了
            return AjaxResult.error("用户已经购买过一次！");
        }

        // 3 减库存
        if (!voucherMapper.updateVoucherWithSeckill(voucherId)) {
            return AjaxResult.error("下单失败");
        }

        // 4 生成订单
        // 4.1. 生成订单id
        Long voucherOrderId = redisIdWorker.nextId("voucher_order");
        if(null == voucherOrderId){
            return AjaxResult.error("订单号生成失败"); // 正常情况不会出现
        }
        // 4.2. 创建订单
        VoucherOrder order = new VoucherOrder();
        order.setId(voucherOrderId);
        order.setUserId(userId.toString());
        order.setVoucherId(voucherId.toString());
        //为了后续方便，这里就简单的返回订单的处理
        if(voucherOrderMapper.insertVoucherOrder(order) != 0){
            return AjaxResult.success("下单成功");
        } else {
            return AjaxResult.error("下单失败");
        }
    }


    /**
     * Data类型转为LocalDataTime类型
     * @param date
     * @return
     */
    private LocalDateTime data2LocalDateTime(Date date){
        Instant instant = date.toInstant();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
        return localDateTime;
    }
}
